package com.mj.haier.calc.web.rest;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import com.codahale.metrics.annotation.Timed;
import com.mj.haier.calc.client.RrskxClient;
import com.mj.haier.calc.service.AzEorderService;
import com.mj.haier.calc.domain.*;
import com.mj.haier.calc.repository.AzEorderSettlementProcessRepository;
import com.mj.haier.calc.repository.AzEorderTitleErrorRepository;
import com.mj.haier.calc.repository.AzEorderTitleRepository;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * AzProcessControlResource controller
 * 安装单流程管控
 */
@RestController
@RequestMapping("/api/az-process-control")
public class AzProcessControlResource {

    private final Logger log = LoggerFactory.getLogger(AzProcessControlResource.class);

    @Resource(name= "taskExecutor")
    private TaskExecutor taskExecutor;

    @Autowired
    private RrskxClient rrskxClient;

    @Autowired
    private AzEorderService azEorderService;

    @Autowired
    private AzEorderTitleErrorRepository azEorderTitleErrorRepository;

    @Autowired
    private AzEorderTitleRepository azEorderTitleRepository;

    @Autowired
    private AzEorderSettlementProcessRepository azEorderSettlementProcessRepository;

    /**
    * GET /sycnAzEorderTitle/{tradeCode}
    *
    * @return
    */
    @GetMapping("/sycnAzEorderTitle/{tradeCode}")
    public String sycnAzEorderTitle(@PathVariable String tradeCode) {

        log.debug("REST request to sycnAzEorderTitle of tradeCode : {}", tradeCode);
        taskExecutor.execute(() -> {
            Integer limit = 250;
            for (;;){
                List<AzEorderTitle> azEorderTitles = rrskxClient.getAllAzEorders(tradeCode, limit);
                log.debug("当前返回的 azEorderTitles : {}", azEorderTitles.toString());
                if(null != azEorderTitles && azEorderTitles.size() > 0){
                    azEorderService.syncBatchAzEorderTitle(azEorderTitles);
                    log.debug("当前线程运行时为 ： {}", Thread.currentThread().getName());
                    try {
                        Thread.sleep(6000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    log.debug("当前tradeCode：{} 同步需结算订单进入财务订单表结束", tradeCode);
                    return;
                }
            }
        });
        return "sycnAzEorderTitle, tradeCode : " + tradeCode + " Running";
    }

    /**
     * GET /backBatchAzEorderTitleError2AzEorderTitle
     * 强制需处理的安装单强制更新
     *
     * @return
     */
    @GetMapping("/backBatchAzEorderTitleError2AzEorderTitle")
    public String backBatchAzEorderTitleError2AzEorderTitle(){

        log.debug("REST request to backBatchAzEorderTitleError2AzEorderTitle");
        String isDeal = "1";
        List<AzEorderTitleError> azEorderTitleErrors = azEorderTitleErrorRepository.findAllByIsDeal(isDeal);
        azEorderService.backBatchAzEorderTitleError2AzEorderTitle(azEorderTitleErrors);
        return "backBatchAzEorderTitleError2AzEorderTitle end";
    }

    /**
     * GET /syncBatchAzEorderSettlementProcess/{tradeCode}/{settlementCycle}
     *   同步结算订单进入临时表
     *
     * @param tradeCode
     * @param settlementCycle 当前的月度
     * @return
     */
    @GetMapping("/syncBatchAzEorderSettlementProcess/{tradeCode}/{settlementCycle}")
    public String syncBatchAzEorderSettlementProcess(@PathVariable String tradeCode, @PathVariable String settlementCycle){

        log.debug("REST request to syncBatchAzEorderSettlementProcess, tradeCode: {}, settlementCycle: {}", tradeCode, settlementCycle);

        taskExecutor.execute(() -> {
            Integer limit = 1000;
            for(;;){
                Pageable pageable = new PageRequest(0, limit);
                List<AzEorderTitle> azEorderTitles = azEorderTitleRepository.findAllByTradeCodeAndIsPublishedLimit(tradeCode, false, pageable);

                if(null != azEorderTitles && azEorderTitles.size() > 0){
                    azEorderService.syncBatchAzEorderSettlementProcess(azEorderTitles, settlementCycle);
                    log.debug("当前线程运行时为 ： {}", Thread.currentThread().getName());
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    log.debug("当前tradeCode：{} 同步结算订单进入临时表结束", tradeCode);
                    return;
                }
            }
        });

        return "syncBatchAzEorderSettlementProcess, tradeCode: " + tradeCode + "; settlementCycle: "+ settlementCycle + " Running";
    }

    /**
     * GET /complianceCheckAzEorderSettlementProcess/{settlementCycle}
     * 合规性检查
     *
     * @param settlementCycle
     * @return
     */
    @GetMapping("/complianceCheckAzEorderSettlementProcess/{settlementCycle}")
    @Timed
    public String complianceCheckAzEorderSettlementProcess(@PathVariable String settlementCycle){

        log.debug("REST request to complianceCheckAzEorderSettlementProcess, settlementCycle: {}", settlementCycle);

        taskExecutor.execute(() -> {
            Integer limit = 100;
            for(;;){
                Pageable pageable = new PageRequest(0, limit);
                List<AzEorderSettlementProcess> processes = azEorderSettlementProcessRepository.findAllBySettlementCycleAndAllComplianceIsNull(settlementCycle, pageable);

                if(null != processes && processes.size() > 0){
                    azEorderService.complianceCheckAzEorderSettlementProcess(processes);
                    log.debug("当前线程运行时为 ： {}", Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    log.debug("当前settlementCycle：{} 下的订单自检完成", settlementCycle);
                    return;
                }
            }
        });
        return "complianceCheckAzEorderSettlementProcess, settlementCycle: "+ settlementCycle + " Running";
    }

    /**
     * GET /complianceCheckAzEorderSettlementProcess/{settlementCycle}/{tradeCode}
     * 合规性检查, 通过赋值 allCompliancce = A，B，C等来区分进程进行检查
     *
     * @param settlementCycle
     * @param allCompliancce
     * @return
     */
    @GetMapping("/complianceCheckAzEorderSettlementProcess/{settlementCycle}/{allCompliancce}")
    public String complianceCheckAzEorderSettlementProcessByTradeCode(@PathVariable String settlementCycle, @PathVariable String allCompliancce){

        log.debug("REST request to complianceCheckAzEorderSettlementProcessByTradeCode, settlementCycle: {}, allCompliancce: {}", settlementCycle, allCompliancce);

        taskExecutor.execute(() -> {
            Integer limit = 100;
            for(;;){
                Pageable pageable = new PageRequest(0, limit);
                List<AzEorderSettlementProcess> processes = azEorderSettlementProcessRepository.findAllBySettlementCycleAndAllCompliance(settlementCycle, allCompliancce, pageable);

                if(null != processes && processes.size() > 0){
                    azEorderService.complianceCheckAzEorderSettlementProcess(processes);
                    log.debug("当前线程运行时为 ： {}", Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    log.debug("当前settlementCycle：{}, allCompliancce: {} 下的订单自检完成", settlementCycle, allCompliancce);
                    return;
                }
            }
        });
        return "complianceCheckAzEorderSettlementProcessByTradeCode, settlementCycle: "+ settlementCycle + ", allCompliancce: "+ allCompliancce +" Running";
    }

    /**
     * GET /deleteNotComplianceAzEorderTitle/{settlementCycle}
     * 不合规检查的订单在源订单表中删除
     *
     * @param settlementCycle
     * @return
     */
    @GetMapping("/deleteNotComplianceAzEorderTitle/{settlementCycle}")
    public String deleteNotComplianceAzEorderTitle(@PathVariable String settlementCycle){

        log.debug("REST request to deleteNotComplianceAzEorderTitle, settlementCycle: {}", settlementCycle);

        taskExecutor.execute(() -> {
            Integer limit = 1000;
            for(;;){
                Pageable pageable = new PageRequest(0, limit);
                List<AzEorderSettlementProcess> processes = azEorderSettlementProcessRepository.findAllBySettlementCycleAndAllCompliance(settlementCycle, "1", pageable);
                if(null != processes && processes.size() > 0){
                    azEorderService.deleteNotComplianceAzEorderTitle(processes);
                    log.debug("当前线程运行时为 ： {}", Thread.currentThread().getName());
                    try {
                        Thread.sleep(6000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    log.debug("当前settlementCycle：{} 下的不合规订单已处理完成", settlementCycle);
                    return;
                }
            }
        });

        return "deleteNotComplianceAzEorderTitle, settlementCycle: " + settlementCycle + " Running";
    }

    /**
     * GET /settlementAzFinSettle/{settlementCycle}/{tradeCode}
     * 合规的安装单，统计生成车队结算单，车辆结算单及相应的明细
     *
     * @param settlementCycle
     * @param tradeCode
     * @return
     */
    @GetMapping("/settlementAzFinSettle/{settlementCycle}/{tradeCode}")
    public String settlementAzFinSettle(@PathVariable String settlementCycle, @PathVariable String tradeCode){

        log.debug("REST request to settlementAzFinSettle, settlementCycle: {}, tradeCode: {}", settlementCycle, tradeCode);

        //获取当前 settlementCycle 下的第一天，与最后一天
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try {
            date = sf.parse(settlementCycle + "01");
        } catch (ParseException e) {
            return "settlementCycle 参数格式不对， 需为yyyyMM";
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        // 当前月第一天
        Instant beginDate = Instant.ofEpochMilli(c.getTimeInMillis()).plusMillis(TimeUnit.HOURS.toMillis(8));
        // 当前月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        Instant endDate = Instant.ofEpochMilli(c.getTimeInMillis()).plusMillis(TimeUnit.HOURS.toMillis(8));

       taskExecutor.execute(() -> {
            //车队
            azEorderService.settlementAzFinSettleCarsteam(settlementCycle, tradeCode, beginDate, endDate);
            //车辆 暂时没有
            // azEorderService.settlementAzFinSettleCars(settlementCycle, tradeCode, beginDate, endDate);
            log.debug("当前settlementCycle：{}, tradeCode : {} 下的结算单已处理完成", settlementCycle, tradeCode);
       });

        return "settlementAzFinSettle , settlementCycle： " + settlementCycle +", tradeCode: "+ tradeCode + " Running";
    }


    /**
     * 激励兑现车队
     * 
     * @param account 周期
     * @param isForSourceNameCode  0: true, 1: false
     * @param initial  null
     * @param target  1
     * @return
     */
    @GetMapping("/encourageCashAzFinSettleCarsteam/{account}/{isForSourceNameCode}/{initial}/{target}")
    public String encourageCashAzFinSettleCarsteam(@PathVariable String account, @PathVariable String isForSourceNameCode,
        @PathVariable String initial, @PathVariable String target){

        log.debug("REST request to encourageCashAzFinSettleCarsteam, account: {}, isForSourceNameCode: {}", account, isForSourceNameCode);

        taskExecutor.execute(() -> {

            // azEorderService.encourageCashAzFinSettleCarsteam(account, isForSourceNameCode);
            Integer limit = 100;
            for(;;){
                List<AzFinSettleCarsteam> carsteams = azEorderService.getCarsteamResultList(account, initial, target, limit);
                if(null != carsteams && carsteams.size() > 0){
                    azEorderService.encourageCashAzFinSettleCarsteam(carsteams, isForSourceNameCode, target);
                    log.debug("当前线程运行时为 ： {}", Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    log.debug("account: {} 下的车队激励兑现周期", account);
                    return;
                }
            }

        });
        return "encourageCashAzFinSettleCarsteam , account " + account +", isForSourceNameCode: "+ isForSourceNameCode + " Running";
    }

    /**
     * 激励兑现车辆
     * 
     * @param account 周期
     * @param isForSourceNameCode 0: true, 1: false
     * @return
     */
    @GetMapping("/encourageCashAzFinSettleCars/{account}/{isForSourceNameCode}")
    public String encourageCashAzFinSettleCars(@PathVariable String account, @PathVariable String isForSourceNameCode){

        log.debug("REST request to encourageCashAzFinSettleCars, account: {}, isForSourceNameCode: {}", account, isForSourceNameCode);

        taskExecutor.execute(() -> {
            azEorderService.encourageCashAzFinSettleCars(account, isForSourceNameCode);
        });
        return "encourageCashAzFinSettleCars , account " + account +", isForSourceNameCode: "+ isForSourceNameCode + " Running";
    }

    /**
     * 根据激励明细生成对应的车队结算单
     * @param settlementCycle
     * @return
     */
    @GetMapping("/encourage4AzFinSettleCarsteam/{settlementCycle}")
    public String encourage4AzFinSettleCarsteam(@PathVariable String settlementCycle){

        log.debug("REST request to encourage4AzFinSettleCarsteam, settlementCycle: {}", settlementCycle);

        //获取当前 settlementCycle 下的第一天，与最后一天
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try {
            date = sf.parse(settlementCycle + "01");
        } catch (ParseException e) {
            return "settlementCycle 参数格式不对， 需为yyyyMM";
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        // 当前月第一天
        Instant beginDate = Instant.ofEpochMilli(c.getTimeInMillis()).plusMillis(TimeUnit.HOURS.toMillis(8));
        // 当前月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        Instant endDate = Instant.ofEpochMilli(c.getTimeInMillis()).plusMillis(TimeUnit.HOURS.toMillis(8));

       taskExecutor.execute(() -> {
            //车队
            azEorderService.encourage4AzFinSettleCarsteam(settlementCycle, beginDate, endDate);

            log.debug("当前settlementCycle：{} 下的结算单已处理完成", settlementCycle);
       });

        return "encourage4AzFinSettleCarsteam , settlementCycle： " + settlementCycle +" Running";
    }

}
